#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Maven安装器 - PyQt5版本
功能：
1. 自动检测操作系统
2. 获取Maven版本列表
3. 提供GUI界面选择版本和安装目录
4. 自动下载和安装Maven
5. 支持深色/浅色主题
"""

import platform
import requests
import os
import sys
import subprocess
import threading
import zipfile
import tarfile
import shutil
import warnings
from datetime import datetime
import time

# 忽略SSL警告
warnings.filterwarnings('ignore', message='urllib3 v2 only supports OpenSSL 1.1.1+')

# 使用最新稳定的Maven版本
MAVEN_VERSION = "3.9.11"
MAVEN_DOWNLOAD_URL = f"https://dlcdn.apache.org/maven/maven-3/{MAVEN_VERSION}/binaries/apache-maven-{MAVEN_VERSION}-bin.tar.gz"
MAVEN_DOWNLOAD_URL_WIN = f"https://dlcdn.apache.org/maven/maven-3/{MAVEN_VERSION}/binaries/apache-maven-{MAVEN_VERSION}-bin.zip"

# 检查是否可以使用PyQt5
try:
    from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, 
                                QHBoxLayout, QLabel, QLineEdit, QPushButton, 
                                QProgressBar, QTextEdit, QFileDialog, QMessageBox,
                                QTabWidget, QGroupBox, QCheckBox, QFrame)
    from PyQt5.QtCore import Qt, QThread, pyqtSignal, QUrl
    from PyQt5.QtGui import QFont, QPalette, QColor
    GUI_AVAILABLE = True
except ImportError:
    print("无法加载PyQt5库，将使用命令行界面")
    GUI_AVAILABLE = False

def detect_os():
    """检测操作系统信息"""
    system = platform.system().lower()
    machine = platform.machine().lower()
    
    os_info = {
        'system': system,
        'machine': machine,
        'platform': platform.platform(),
        'version': platform.version()
    }
    
    # 确定下载文件扩展名
    if system == 'windows':
        os_info['extension'] = 'zip'
        os_info['binary_name'] = 'mvn.cmd'
        os_info['download_url'] = MAVEN_DOWNLOAD_URL_WIN
    else:  # macOS/Linux
        os_info['extension'] = 'tar.gz'
        os_info['binary_name'] = 'mvn'
        os_info['download_url'] = MAVEN_DOWNLOAD_URL
    
    return os_info

def get_default_install_path(os_info):
    """获取默认安装路径（用户目录下，避免权限问题）"""
    home_dir = os.path.expanduser("~")
    
    if os_info['system'] == 'windows':
        return os.path.join(home_dir, 'Maven')
    else:  # macOS/Linux
        return os.path.join(home_dir, 'maven')

def download_file(url, filepath, progress_callback=None):
    """下载文件"""
    print(f"开始下载: {url}")
    response = requests.get(url, stream=True, timeout=30)
    response.raise_for_status()
    
    total_size = int(response.headers.get('content-length', 0))
    downloaded_size = 0
    start_time = time.time()
    
    with open(filepath, 'wb') as f:
        for chunk in response.iter_content(chunk_size=8192):
            f.write(chunk)
            downloaded_size += len(chunk)
            
            if total_size > 0:
                progress = (downloaded_size / total_size) * 100
                elapsed_time = time.time() - start_time
                
                if elapsed_time > 0:
                    speed = downloaded_size / elapsed_time / 1024  # KB/s
                    
                    # 如果提供了回调函数，调用它
                    if progress_callback:
                        progress_callback(progress, downloaded_size, total_size, speed)
                    else:
                        print(f"\r下载进度: {progress:.1f}% ({downloaded_size//1024//1024}MB/{total_size//1024//1024}MB) - {speed:.1f} KB/s", end='')
                else:
                    if progress_callback:
                        progress_callback(progress, downloaded_size, total_size, 0)
                    else:
                        print(f"\r下载进度: {progress:.1f}% ({downloaded_size//1024//1024}MB/{total_size//1024//1024}MB)", end='')
    
    print("\n下载完成!")

def extract_file(filepath, extract_dir):
    """解压文件"""
    print("开始解压...")
    if filepath.endswith('.zip'):
        with zipfile.ZipFile(filepath, 'r') as zip_ref:
            zip_ref.extractall(extract_dir)
    elif filepath.endswith('.tar.gz'):
        with tarfile.open(filepath, 'r:gz') as tar_ref:
            tar_ref.extractall(extract_dir)
    print("解压完成!")

def show_environment_setup_cli(maven_home, os_info):
    """显示环境变量配置信息（命令行版本）"""
    bin_path = os.path.join(maven_home, "bin")
    
    print("\nMaven安装完成!")
    print(f"\n安装路径: {maven_home}")
    print("\n请手动配置环境变量：")
    
    if os_info['system'] == 'windows':
        print(f"\nWindows:")
        print(f"set MAVEN_HOME={maven_home}")
        print(f"set PATH=%PATH%;{bin_path}")
    else:
        print(f"\nmacOS/Linux:")
        print(f"export MAVEN_HOME={maven_home}")
        print(f"export PATH=$PATH:{bin_path}")
        print(f"\n或者将以下内容添加到 ~/.bashrc 或 ~/.zshrc:")
        print(f"export MAVEN_HOME={maven_home}")
        print(f"export PATH=$PATH:{bin_path}")
    
    print("\n配置完成后，请重新打开终端并运行 'mvn --version' 验证安装。")

def install_maven_cli():
    """命令行版本的安装流程"""
    print("=== Maven安装器 (命令行版本) ===\n")
    
    # 检测操作系统
    os_info = detect_os()
    print(f"检测到操作系统: {os_info['platform']}")
    print(f"系统架构: {os_info['machine']}\n")
    
    # 使用固定版本
    selected_version = MAVEN_VERSION
    print(f"使用稳定版本: Maven {selected_version}")
    
    # 选择安装目录
    default_path = get_default_install_path(os_info)
    install_path = default_path
    try:
        user_path = input(f"请输入安装目录 (默认: {default_path}): ").strip()
        if user_path:
            install_path = user_path
    except:
        print(f"使用默认安装路径: {default_path}")
    
    print(f"安装目录: {install_path}")
    print()
    
    # 确认安装
    confirm = "y"  # 默认确认
    try:
        confirm = input("确认开始安装? (y/N): ").strip().lower()
    except:
        print("使用默认选择: y")
    
    if confirm in ['y', 'yes'] or not confirm:
        try:
            print(f"开始安装Maven {selected_version}")
            print(f"安装目录: {install_path}")
            
            # 创建安装目录
            os.makedirs(install_path, exist_ok=True)
            
            # 下载Maven
            download_url = os_info['download_url']
            print(f"下载URL: {download_url}")
            
            # 下载文件
            filename = f"apache-maven-{selected_version}-bin.{os_info['extension']}"
            filepath = os.path.join(install_path, filename)
            
            download_file(download_url, filepath)
            
            # 解压文件
            extract_file(filepath, install_path)
            
            # 移动文件到最终位置
            extracted_dir = os.path.join(install_path, f"apache-maven-{selected_version}")
            final_dir = os.path.join(install_path, "maven")
            
            if os.path.exists(final_dir):
                shutil.rmtree(final_dir)
            shutil.move(extracted_dir, final_dir)
            
            # 清理下载文件
            os.remove(filepath)
            
            print("Maven安装完成!")
            
            # 显示环境变量配置信息
            show_environment_setup_cli(final_dir, os_info)
            
        except Exception as e:
            print(f"安装失败: {str(e)}")
    else:
        print("安装已取消")

# 如果GUI可用，定义PyQt5版本的下载线程和主窗口
if GUI_AVAILABLE:
    class DownloadThread(QThread):
        """下载线程"""
        progress_signal = pyqtSignal(float, int, int, float)
        finished_signal = pyqtSignal(bool, str)
        log_signal = pyqtSignal(str)
        
        def __init__(self, url, filepath):
            super().__init__()
            self.url = url
            self.filepath = filepath
            self.is_cancelled = False
        
        def run(self):
            try:
                self.log_signal.emit(f"开始下载: {self.url}")
                response = requests.get(self.url, stream=True, timeout=30)
                response.raise_for_status()
                
                total_size = int(response.headers.get('content-length', 0))
                downloaded_size = 0
                start_time = time.time()
                
                with open(self.filepath, 'wb') as f:
                    for chunk in response.iter_content(chunk_size=8192):
                        if self.is_cancelled:
                            self.log_signal.emit("下载已取消")
                            self.finished_signal.emit(False, "下载已取消")
                            return
                        
                        f.write(chunk)
                        downloaded_size += len(chunk)
                        
                        if total_size > 0:
                            progress = (downloaded_size / total_size) * 100
                            elapsed_time = time.time() - start_time
                            
                            if elapsed_time > 0:
                                speed = downloaded_size / elapsed_time / 1024  # KB/s
                                self.progress_signal.emit(progress, downloaded_size, total_size, speed)
                
                self.log_signal.emit("下载完成!")
                self.finished_signal.emit(True, "")
                
            except Exception as e:
                self.log_signal.emit(f"下载失败: {str(e)}")
                self.finished_signal.emit(False, str(e))
        
        def cancel(self):
            self.is_cancelled = True
    
    class MavenInstallerWindow(QMainWindow):
        """Maven安装器主窗口"""
        def __init__(self):
            super().__init__()
            
            self.os_info = detect_os()
            self.install_path = get_default_install_path(self.os_info)
            self.download_thread = None
            self.dark_mode = False
            
            self.init_ui()
        
        def init_ui(self):
            """初始化UI"""
            self.setWindowTitle("Maven安装器")
            self.setGeometry(100, 100, 700, 600)
            
            # 创建中央窗口部件
            central_widget = QWidget()
            self.setCentralWidget(central_widget)
            
            # 主布局
            main_layout = QVBoxLayout(central_widget)
            
            # 创建选项卡
            tabs = QTabWidget()
            main_layout.addWidget(tabs)
            
            # 安装选项卡
            install_tab = QWidget()
            tabs.addTab(install_tab, "安装Maven")
            
            # 设置选项卡
            settings_tab = QWidget()
            tabs.addTab(settings_tab, "设置")
            
            # 设置安装选项卡
            self.setup_install_tab(install_tab)
            
            # 设置设置选项卡
            self.setup_settings_tab(settings_tab)
        
        def setup_install_tab(self, tab):
            """设置安装选项卡"""
            layout = QVBoxLayout(tab)
            
            # 系统信息组
            system_group = QGroupBox("系统信息")
            system_layout = QVBoxLayout(system_group)
            
            system_info = QLabel(f"操作系统: {self.os_info['platform']}")
            system_layout.addWidget(system_info)
            
            arch_info = QLabel(f"系统架构: {self.os_info['machine']}")
            system_layout.addWidget(arch_info)
            
            layout.addWidget(system_group)
            
            # Maven版本组
            version_group = QGroupBox("Maven版本")
            version_layout = QVBoxLayout(version_group)
            
            version_info = QLabel(f"版本: {MAVEN_VERSION}")
            version_layout.addWidget(version_info)
            
            layout.addWidget(version_group)
            
            # 安装目录组
            path_group = QGroupBox("安装目录")
            path_layout = QHBoxLayout(path_group)
            
            path_label = QLabel("安装路径:")
            path_layout.addWidget(path_label)
            
            self.path_edit = QLineEdit(self.install_path)
            path_layout.addWidget(self.path_edit)
            
            browse_btn = QPushButton("浏览")
            browse_btn.clicked.connect(self.browse_directory)
            path_layout.addWidget(browse_btn)
            
            layout.addWidget(path_group)
            
            # 进度组
            progress_group = QGroupBox("安装进度")
            progress_layout = QVBoxLayout(progress_group)
            
            progress_hlayout = QHBoxLayout()
            self.progress_bar = QProgressBar()
            progress_hlayout.addWidget(self.progress_bar)
            
            self.progress_label = QLabel("准备就绪")
            progress_hlayout.addWidget(self.progress_label)
            
            progress_layout.addLayout(progress_hlayout)
            
            self.detail_label = QLabel("")
            progress_layout.addWidget(self.detail_label)
            
            layout.addWidget(progress_group)
            
            # 日志组
            log_group = QGroupBox("安装日志")
            log_layout = QVBoxLayout(log_group)
            
            self.log_text = QTextEdit()
            self.log_text.setReadOnly(True)
            log_layout.addWidget(self.log_text)
            
            layout.addWidget(log_group)
            
            # 按钮布局
            button_layout = QHBoxLayout()
            
            self.install_btn = QPushButton("开始安装")
            self.install_btn.clicked.connect(self.start_installation)
            button_layout.addWidget(self.install_btn)
            
            self.cancel_btn = QPushButton("取消")
            self.cancel_btn.clicked.connect(self.cancel_installation)
            self.cancel_btn.setEnabled(False)
            button_layout.addWidget(self.cancel_btn)
            
            button_layout.addStretch()
            
            layout.addLayout(button_layout)
        
        def setup_settings_tab(self, tab):
            """设置设置选项卡"""
            layout = QVBoxLayout(tab)
            
            # 主题设置组
            theme_group = QGroupBox("主题设置")
            theme_layout = QVBoxLayout(theme_group)
            
            self.theme_check = QCheckBox("深色模式")
            self.theme_check.toggled.connect(self.toggle_theme)
            theme_layout.addWidget(self.theme_check)
            
            layout.addWidget(theme_group)
            
            # 关于组
            about_group = QGroupBox("关于")
            about_layout = QVBoxLayout(about_group)
            
            about_text = """Maven安装器

版本: 1.0.0
作者: AI助手
描述: 一个用于自动安装Maven的图形界面工具

功能:
- 自动检测操作系统
- 自动下载和安装Maven
- 主题切换
"""
            
            about_label = QLabel(about_text)
            about_layout.addWidget(about_label)
            
            layout.addWidget(about_group)
            
            layout.addStretch()
        
        def browse_directory(self):
            """浏览选择安装目录"""
            directory = QFileDialog.getExistingDirectory(self, "选择Maven安装目录", self.install_path)
            if directory:
                self.path_edit.setText(directory)
                self.install_path = directory
        
        def log_message(self, message):
            """添加日志消息"""
            timestamp = datetime.now().strftime('%H:%M:%S')
            self.log_text.append(f"[{timestamp}] {message}")
            
            # 滚动到底部
            cursor = self.log_text.textCursor()
            cursor.movePosition(cursor.End)
            self.log_text.setTextCursor(cursor)
        
        def update_progress(self, progress, downloaded, total, speed):
            """更新进度条和标签"""
            self.progress_bar.setValue(int(progress))
            self.progress_label.setText(f"下载中... {downloaded//1024//1024}MB/{total//1024//1024}MB")
            self.detail_label.setText(f"速度: {speed:.1f} KB/s")
        
        def toggle_theme(self, checked):
            """切换主题"""
            self.dark_mode = checked
            self.apply_theme()
        
        def apply_theme(self):
            """应用主题"""
            app = QApplication.instance()
            
            if self.dark_mode:
                # 深色主题
                palette = QPalette()
                palette.setColor(QPalette.Window, QColor(53, 53, 53))
                palette.setColor(QPalette.WindowText, Qt.white)
                palette.setColor(QPalette.Base, QColor(25, 25, 25))
                palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
                palette.setColor(QPalette.ToolTipBase, Qt.white)
                palette.setColor(QPalette.ToolTipText, Qt.white)
                palette.setColor(QPalette.Text, Qt.white)
                palette.setColor(QPalette.Button, QColor(53, 53, 53))
                palette.setColor(QPalette.ButtonText, Qt.white)
                palette.setColor(QPalette.BrightText, Qt.red)
                palette.setColor(QPalette.Link, QColor(42, 130, 218))
                palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
                palette.setColor(QPalette.HighlightedText, Qt.black)
                app.setPalette(palette)
            else:
                # 浅色主题
                app.setPalette(app.style().standardPalette())
        
        def start_installation(self):
            """开始安装"""
            self.install_path = self.path_edit.text()
            
            if not self.install_path:
                QMessageBox.critical(self, "错误", "请选择安装目录")
                return
            
            # 确认安装
            reply = QMessageBox.question(
                self, 
                "确认安装",
                f"确定要安装Maven {MAVEN_VERSION} 到 {self.install_path} 吗？",
                QMessageBox.Yes | QMessageBox.No,
                QMessageBox.No
            )
            
            if reply == QMessageBox.Yes:
                self.install_btn.setEnabled(False)
                self.cancel_btn.setEnabled(True)
                self.progress_bar.setValue(0)
                self.progress_label.setText("准备中...")
                
                # 开始安装流程
                self.install_maven()
        
        def cancel_installation(self):
            """取消安装"""
            if self.download_thread and self.download_thread.isRunning():
                self.download_thread.cancel()
            
            self.log_message("安装已取消")
            self.install_btn.setEnabled(True)
            self.cancel_btn.setEnabled(False)
        
        def install_maven(self):
            """安装Maven"""
            try:
                # 创建安装目录
                os.makedirs(self.install_path, exist_ok=True)
                
                # 下载Maven
                download_url = self.os_info['download_url']
                self.log_message(f"下载URL: {download_url}")
                
                # 下载文件
                filename = f"apache-maven-{MAVEN_VERSION}-bin.{self.os_info['extension']}"
                filepath = os.path.join(self.install_path, filename)
                
                # 创建下载线程
                self.download_thread = DownloadThread(download_url, filepath)
                self.download_thread.progress_signal.connect(self.update_progress)
                self.download_thread.finished_signal.connect(lambda success, error: self.download_finished(success, error, filepath))
                self.download_thread.log_signal.connect(self.log_message)
                self.download_thread.start()
                
            except Exception as e:
                self.log_message(f"安装准备失败: {str(e)}")
                self.install_btn.setEnabled(True)
                self.cancel_btn.setEnabled(False)
        
        def download_finished(self, success, error, filepath):
            """下载完成回调"""
            if not success:
                self.log_message(f"下载失败: {error}")
                self.install_btn.setEnabled(True)
                self.cancel_btn.setEnabled(False)
                return
            
            # 解压文件
            try:
                self.log_message("开始解压...")
                self.progress_label.setText("正在解压...")
                
                extract_file(filepath, self.install_path)
                
                # 移动文件到最终位置
                extracted_dir = os.path.join(self.install_path, f"apache-maven-{MAVEN_VERSION}")
                final_dir = os.path.join(self.install_path, "maven")
                
                if os.path.exists(final_dir):
                    shutil.rmtree(final_dir)
                shutil.move(extracted_dir, final_dir)
                
                # 清理下载文件
                os.remove(filepath)
                
                self.log_message("Maven安装完成！")
                self.progress_label.setText("安装完成")
                self.progress_bar.setValue(100)
                
                # 显示环境变量配置信息
                self.show_environment_setup(final_dir)
                
            except Exception as e:
                self.log_message(f"安装失败: {str(e)}")
            finally:
                self.install_btn.setEnabled(True)
                self.cancel_btn.setEnabled(False)
        
        def show_environment_setup(self, maven_home):
            """显示环境变量配置信息"""
            bin_path = os.path.join(maven_home, "bin")
            
            env_info = f"""
Maven安装完成！

安装路径: {maven_home}

请手动配置环境变量：

Windows:
set MAVEN_HOME={maven_home}
set PATH=%PATH%;{bin_path}

macOS/Linux:
export MAVEN_HOME={maven_home}
export PATH=$PATH:{bin_path}

或者将以下内容添加到 ~/.bashrc 或 ~/.zshrc:
export MAVEN_HOME={maven_home}
export PATH=$PATH:{bin_path}

配置完成后，请重新打开终端并运行 'mvn --version' 验证安装。
"""
            
            # 显示配置信息对话框
            msg_box = QMessageBox(self)
            msg_box.setWindowTitle("环境变量配置")
            msg_box.setText(env_info)
            msg_box.setTextInteractionFlags(Qt.TextSelectableByMouse | Qt.TextSelectableByKeyboard)
            
            # 添加复制按钮
            copy_button = msg_box.addButton("复制到剪贴板", QMessageBox.ActionRole)
            close_button = msg_box.addButton("关闭", QMessageBox.RejectRole)
            
            msg_box.exec_()
            
            if msg_box.clickedButton() == copy_button:
                clipboard = QApplication.clipboard()
                clipboard.setText(env_info)
                QMessageBox.information(self, "成功", "环境变量配置信息已复制到剪贴板")

def main():
    # 尝试使用GUI，如果失败则使用命令行
    if GUI_AVAILABLE:
        try:
            app = QApplication(sys.argv)
            window = MavenInstallerWindow()
            window.show()
            sys.exit(app.exec_())
        except Exception as e:
            print(f"GUI启动失败: {str(e)}")
            print("切换到命令行模式")
            install_maven_cli()
    else:
        install_maven_cli()

if __name__ == "__main__":
    main()
